/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package filereader;

import indexfileprocessor.IndexFileWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import model.FieldList;
import model.Message;
import model.PostingList;
import tokenizer.TokenMessage;
import util.Cleaner;

/**
 *
 * @author Danang
 */
public class MessageReader {

    List<File> fileList; // list dari file
    Cleaner cleaner; // thread untuk memanggil GC
    
    // Tokenizer
    TokenMessage tokenizer;
    
    // IndexFileWriter
    IndexFileWriter writer;
    public MessageReader(List<File> list) {
        this.fileList = list;
        cleaner = new Cleaner();
        tokenizer = new TokenMessage();
        writer = new IndexFileWriter();
    }

    // prosedur untuk memulai kerja message reader
    public void run() throws IOException {
        cleaner.activateGC();
        System.out.println("Starting to add query for tokenizing message...");
        
        int sizeAll = fileList.size();
        Message result;
        // Get the Java runtime
        Runtime runtime = Runtime.getRuntime();
        long last_saved_memory = 0;
        for (int a = 0; a < sizeAll; a++) {
            // read file here
            result = readContent(fileList.get(a));
            // do tokenizer here
            tokenizer.token_it(result);
            
            if (a != 0 && a % 1000 == 0) {
                System.out.println("File processed " + a);
            }
            
            if (a != 0 && a % 5000 == 0) {
                // Calculate the used memory
                long memory = runtime.totalMemory() - runtime.freeMemory();
                System.out.println("Used Memory "+memory);
                printTokenizer(a);
                tokenizer.reinit();
            }
            result = null;
        }
        printTokenizer(sizeAll);
        tokenizer.reinit();
        System.out.println("-> Finished getting tokenizing results.");
    }

    // prosedur untuk mengakhiri reader
    public void terminate() {
        cleaner.terminate();
    }
    
    private void printTokenizer(int a) throws IOException {
        BufferedWriter out = new BufferedWriter(new FileWriter("file "+a));
        System.out.println("Starting to write inverted index");
        List<FieldList> tmp = tokenizer.getTokenList().sortToken();
        System.out.println("Finished Sorting "+tmp.size()+" tokens");
        StringBuilder sb = new StringBuilder();
        for(FieldList fl : tmp) {
            sb.append("@@").append(fl.getToken()).append("\n");
            sb.append(fl.getAllPostingList());
        }
        out.write(sb.toString());
        System.out.println("Writing to file");
        //writer.writeToFile(tm, "body");
        System.out.println("Reinit tokenizer");
        out.close();
    }

    /**
     * fungsi yang melakukan pembacaan konten (message) yang ada pada suatu file
     * @param a file yang menjadi masukan
     * @return message yang merupakan kelas yang menggambarkan konten suatu file
     */
    public static Message readContent(File a) {
        BufferedReader br;
        Message m = new Message();
        boolean isBody = false;
        boolean isTo = false;
        boolean isSkip = false;
        try {
            br = new BufferedReader(new FileReader(a));
            String line = br.readLine();
            int idx_str = 0;
            while (line != null) {
                if (isSkip) { //mengecek apakah baris yang dibaca bukan merupakan bagian body
                    if (line.startsWith("Content-Type: text/plain")) {
                        isBody = true;
                        isSkip = false;
                    }
                } else if (isBody) { //mengecek apakah baris yang dibaca merupakan bagian body
                    if (line.startsWith("Content-Type:")) {
                        isBody = false;
                        isSkip = true;
                    } else {
                        m.addBody(line + "\n");
                    }
                } else if (line.startsWith("Date: ")) { //mengecek apakah baris yang dibaca merupakan bagian date
                    m.setDate(line.substring(6));
                    m.setDateIdx(idx_str+6);
                } else if (line.startsWith("From: ")) { //mengecek apakah baris yang dibaca merupakan bagian from
                    m.setFrom(line.substring(6));
                    m.setFromIdx(idx_str+6);
                } else if (line.startsWith("To: ")) { //mengecek apakah baris yang dibaca merupakan bagian to
                    m.setTo(line.substring(4));
                    m.setToIdx(idx_str+4);
                    isTo = true;
                } else if (line.startsWith("Subject: ")) { //mengecek apakah baris yang dibaca merupakan bagian subject
                    m.setSubject(line.substring(9));
                    m.setSubjectIdx(idx_str+9);
                    isTo = false;
                } else if (line.startsWith("X-FileName: ")) { //mengecek apakah baris yang dibaca merupakan awal bagian body
                    isBody = true;
                    isTo = false;
                    m.setBody("");
                    m.setBodyIdx(idx_str+line.length()+1);
                } else if (isTo) { //mengecek apakah baris yang dibaca masih merupakan bagian to
                    m.setTo(m.getTo() + "\n" + line);
                }
                
                idx_str += line.length()+1;
                line = br.readLine();
            }
            br.close();
        } catch (Exception e) {
            System.out.println("Error read file " + e.getMessage());
        }
        return m;
    }
}

